需要 #include <stdarg.h>
。
包括一個類型,四個巨集函數:
類型: va_list
,用來儲存巨集va_arg()
與巨集va_end()
所需資訊
巨集函數: va_start()
, va_arg()
, va_end()
, va_copy()
除了 va_copy()
是 C99 外,其餘都是相容於 C89 。
int sum(int num, ...){
va_list args;
va_start(args, num);
int sum = 0;
for(i = 0; i < num; i++){
sum += va_arg(args, int);
}
va_end(args);
return sum;
}
先創建一個 va_list
類型的變數,
va_start()
有兩個參數,第一個是剛剛宣告的變數( va_list
類型),
第二個是 可變參數 ...
前一個的變數名,這裏是 num
。
va_arg()
用於獲得額外參數的數值,同樣有兩個參數,
第一個也是剛剛宣告的變數,第二個是 載入的參數類型。
注意 載入的參數類型 不可為
會有默认参数提升(default argument promotions)
va_end()
,像 fclose()
一樣把可變參數關掉。
一個參數,va_list
類型的變數。
詳細實現及原理可參看 可变参数函数详解 - clover_toeic - 博客园
由 C99 引入,
聲明語法類似於可變參數函數:逗號後面三個句點"...",表示一個或多個參數。
但常見編譯器也允許傳遞0個參數。
宏擴展時使用特殊標識符__VA_ARGS__表示所傳遞的參數的替換。
沒辦法訪問可變參數列表內的單個參數,也不能獲知多少個參數被傳遞。
例子:
#define foo(f, ...) printf(f, __VA_ARGS__)
foo("%d%d", x, y);
等價 printf("%d%d", x, y);
接收了兩個額外參數。
注意 沒辦法訪問可變參數列表內的單個參數,也不能獲知多少個參數被傳遞。
所以不能夠像可變參數函數一樣,
可以以“簡單直觀”的方法去實現可變參數的 sum()。
若果額外參數的數目為 0 ,即 foo("123");
,
會被展開為 printf("123",)
,這裏出現了一個額外的逗號。
可把 __VA_ARGS__
改為 ##__VA_ARGS__
,
去提示編譯器,會自動把逗號去除。
Visual C++ 貌似不用提醒也會自動去除。
stdarg.h - 維基百科,自由的百科全書
https://zh.wikipedia.org/wiki/Stdarg.h
可变参数函数详解 - clover_toeic - 博客园
https://www.cnblogs.com/clover-toeic/p/3736748.html
可變參數宏 - 維基百科,自由的百科全書
https://zh.wikipedia.org/wiki/%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E5%AE%8F
C语言可变参数宏定义方法 - 做一个有技术追求的人 - CSDN博客
https://blog.csdn.net/skyflying2012/article/details/38436711
__VA_ARGS__ 與 ## 小檔案 變數是否存在 去除逗號 , @ CC :: 隨意窩 Xuite日誌
https://blog.xuite.net/csiewap/cc/66750644-VA_ARGS+%E8%88%87+%23%23+%E5%B0%8F%E6%AA%94%E6%A1%88+%E8%AE%8A%E6%95%B8%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8+%E5%8E%BB%E9%99%A4%E9%80%97%E8%99%9F+%2C
microsoft Variadic 巨集
https://msdn.microsoft.com/zh-tw/library/ms177415.aspx